﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web;
using ATTools.Models;
using Orchard;
using Orchard.Caching;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Media.Services;
using Orchard.Services;
using Orchard.Settings;
using Orchard.UI.Notify;

namespace ATTools.Services
{
    [OrchardFeature("ATTools")]
    public class SpeakService : ISpeakService
    {
        private readonly ISiteService _siteService;
        private readonly IMediaService _mediaService;
        private readonly ICacheManager _cacheManager;
        private readonly IClock _clock;
        public IOrchardServices Services { get; private set; }

        public Localizer T { get; set; }

        public SpeakService(IOrchardServices services, ISiteService siteService, IMediaService mediaService, ICacheManager cacheManager, IClock clock)
        {
            _siteService = siteService;
            _mediaService = mediaService;
            _cacheManager = cacheManager;
            _clock = clock;
            Services = services;

            T = NullLocalizer.Instance;
        }

        #region ISpeakService Members

        public IEnumerable<string> GetAvailableLanguages()
        {

            IEnumerable<string> voices = new List<string>();

            voices = _cacheManager.Get("bingSpeakLanguages", ctx =>
            {
                var part = _siteService.GetSiteSettings().As<ATToolsSettingsPart>();

                IEnumerable<string> languages = new List<string>();

                string appId = part.Record.BingAppID;
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForSpeak?appId=" + appId;

                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);

                try
                {
                    WebResponse resp = httpWebRequest.GetResponse();
                    Stream strm = resp.GetResponseStream();
                    System.Runtime.Serialization.DataContractSerializer dcs = new System.Runtime.Serialization.DataContractSerializer(typeof(List<string>));
                    languages = (List<string>)dcs.ReadObject(strm);
                }
                catch (Exception)
                {
                    Services.Notifier.Error(T("Please check your Bing App ID"));
                    ctx.Monitor(_clock.When(TimeSpan.FromDays(0)));
                    return languages;
                }
                //Cache the languages for 24 hours
                ctx.Monitor(_clock.When(TimeSpan.FromDays(1)));
                return languages;
            });

            return voices;
            
        }

        public string SaveTextAsSoundFile(string text, string language, string folderName, string fileName)
        {

            var part = _siteService.GetSiteSettings().As<ATToolsSettingsPart>();
            string appId = part.Record.BingAppID;

            List<string> subs = new List<string>();

            int maxLength = 200;
            string textToSub = text;
            while (textToSub != string.Empty)
            {
                string sub = textToSub;
                if (textToSub.Length > maxLength)
                {
                    sub = textToSub.Substring(0, maxLength);
                    sub = sub.Substring(0, sub.LastIndexOf(' '));
                }

                subs.Add(sub);
                textToSub = textToSub.Substring(sub.Length).Trim();
            }

            List<byte> byteList = new List<byte>();

            

            byte[] fullData = null;
            foreach (var t in subs)
            {
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=" + appId +
                    "&text=" + HttpUtility.UrlEncode(HttpUtility.HtmlDecode(t)) + "&language=" + language;

                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
                using (WebResponse resp = httpWebRequest.GetResponse())
                using (Stream strm = resp.GetResponseStream())
                { 

                    if (fullData == null)
                    {
                        fullData = Helpers.WaveHelper.StreamToBytes(strm);
                    }
                    else
                    {
                        using (Stream partialDataStream = new MemoryStream(fullData))
                        using (Stream nextPartialDataStream = new MemoryStream(Helpers.WaveHelper.StreamToBytes(strm)))
                        {
                            try
                            {
                                fullData = Helpers.WaveHelper.MergeWave(partialDataStream, nextPartialDataStream);
                            }
                            catch (Exception e)
                            {
                                Services.Notifier.Error(T("Please check your Bing App ID"));
                            }
                        }
                    }

                }
            }


            try
            {
                _mediaService.CreateFolder(null, folderName);
            }
            catch
            {
                ;
            }

            return _mediaService.UploadMediaFile(folderName, fileName, fullData, false);

        }

        #endregion
    }
}